#include "udp_backend.h"
#include <QNetworkDatagram>

UDPBackend::UDPBackend(QObject *parent) : QObject{parent}
{
    socket = new QUdpSocket(this);
}

UDPBackend::~UDPBackend()
{
    if (socket)
        socket->abort();
    delete socket;
}
bool UDPBackend::Init(unsigned short port)
{
    if (!socket)
        return false;
    if (socket->state() == QAbstractSocket::BoundState)
    {
        socket->abort();
    }
    QAbstractSocket::SocketState state = socket->state();
    if (state == QAbstractSocket::BoundState)
    {
        socket->abort();
    }
    if (state == QAbstractSocket::UnconnectedState)
    {
        bool success = socket->bind(QHostAddress::Any, port);
        if (success)
        {
            connect(socket, &QUdpSocket::readyRead, this, &UDPBackend::OnReceiveDiagram);
            return true;
        }
    }
    throw std::runtime_error("socket state exception");
}
void UDPBackend::SendFrame(const QByteArray &frameData, const QHostAddress &address, unsigned short port)
{
    if (socket->state() != QAbstractSocket::ConnectedState)
    {
        throw std::runtime_error("socket state is not connected when send frame");
    }
    socket->writeDatagram(frameData, address, port);
}

void UDPBackend::OnReceiveDiagram()
{
    if (!socket->hasPendingDatagrams() || socket->pendingDatagramSize() <= 0)
        return;
    while (socket->pendingDatagramSize() > 0)
    {
        QNetworkDatagram diagram = socket->receiveDatagram();
        emit this->OnReceiveFrame(diagram.data());
    }
}
